﻿using System;
using System.Collections.Generic;
using System.Linq;
using ZQNB.BaseLib.Core.Models;
using ZQNB.Common;

namespace ZQNB.BaseLib.Core.Services
{
    public class SideBarMenuConvertor : ISideBarMenuConvertor
    {
        public MenuTreeNode ConvertToTree(IList<SideBarMenu> menusInPosition)
        {

            int positionCount = menusInPosition.Select(x => x.Position).Distinct().Count();
            if (positionCount != 1)
            {
                throw new ArgumentException("只能是同一个Position的菜单才能生成一颗树");
            }

            Func<SideBarMenu, string> getPk = menu => menu.Pk;
            Func<SideBarMenu, string> getParentPk = menu => menu.ParentPk;
            MyTree<SideBarMenu> tree = MyTreeHelper.MakeTree(menusInPosition, getPk, getParentPk);

            MenuTreeNode treeNode = ConvertMyTreeToTreeNode(tree);
            return treeNode;
        }
        
        private static MenuTreeNode ConvertMyTreeToTreeNode(MyTree<SideBarMenu> tree)
        {
            MenuTreeNode treeNode = ConvertMenuToTreeNode(tree.Value);
            foreach (var child in tree.Children)
            {
                MenuTreeNode childNode = ConvertMyTreeToTreeNode(child);
                treeNode.AddChild(childNode);
            }
            return treeNode;
        }

        private static MenuTreeNode ConvertMenuToTreeNode(SideBarMenu menu)
        {
            MenuTreeNode treeNode = new MenuTreeNode()
            {
                Id = menu.Id,
                Href = menu.Href,
                Text = menu.Text,
                Class = menu.Class,
                Positon = menu.Position,
                Module = menu.Module,
                SortNum = menu.SortNum,
                Pk = menu.Pk,
                ParentPk = menu.ParentPk
            };
            return treeNode;
        }


        public IList<SideBarMenu> ConvertToList(MenuTreeNode rootNode)
        {
            List<SideBarMenu> list = new List<SideBarMenu>();
            AppendMenuList(ref list, rootNode);
            return list;
        }

        private static void AppendMenuList(ref List<SideBarMenu> list, MenuTreeNode treeNode)
        {
            var menu = ConvertTreeNodeToMenu(treeNode);
            list.Add(menu);
            //孩子
            foreach (var child in treeNode.Children)
            {
                AppendMenuList(ref list, child);
            }
        }
        private static SideBarMenu ConvertTreeNodeToMenu(MenuTreeNode treeNode)
        {
            SideBarMenu menu = new SideBarMenu()
            {
                Id = treeNode.Id,
                Href = treeNode.Href,
                Text = treeNode.Text,
                Class = treeNode.Class,
                Position = treeNode.Positon,
                Module = treeNode.Module,
                SortNum = treeNode.SortNum,
                Pk = treeNode.Pk,
                ParentPk = treeNode.ParentPk
            };
            return menu;
        }
    }
}